#!/usr/bin/python

# InnerSpace
# Copyright (C) 1999-2006 Phil Christensen
#
# $Id: prop.py 143 2007-02-05 02:05:20Z phil $
#
# See LICENSE for details

"""
Property

Stability: barely stable

"""

from inner.space import code, auth, parser, security

try:
	import cPickle as pickle
except:
	import pickle

EVAL_STRING = 0
EVAL_CODE = 1
EVAL_PICKLE = 2
EVAL_ENTITY = 3
EVAL_DYNAMIC_CODE = 4

class Property:	
	def __init__(self, value, owner, host_object, eval_type=None):
		"""
		Create a new property object.
		"""
		self._vitals = {'acl':[], 'owner':owner, 'host_object':host_object}
		if(eval_type is None):
			eval_type = EVAL_STRING
		self.eval_type = int(eval_type)
		self.set_value(value)
		security.default_property_acl(self)
	
	def set_value(self, value):
		if(self.eval_type == EVAL_STRING):
			self.value = value
		elif(self.eval_type == EVAL_PICKLE):
			self.value = pickle.loads(value)
		elif(self.eval_type == EVAL_ENTITY):
			# since we need the registry to parse the string version
			# of this, we just deal with that on access
			self.value = value
		elif(self.eval_type == EVAL_DYNAMIC_CODE or self.eval_type == EVAL_CODE):
			self.code = value
			if(self.eval_type == EVAL_CODE):
				p = parser.Parser(None, auth.get_current_user(), auth.get_registry())
				env = code.get_environment(None, p)
				env['this'] = self._vitals['host_object']
				if(self.code):
					# helps when loading xml
					self.value = code.r_eval(self.code, env)
		else:
			raise TypeError("Invalid property type: '%s'" % str(self.eval_type))

	
	def get_value(self):
		"""
		Get the value of this property.
		"""
		security.check_allowed(auth.get_current_user(), "read", self)
		if(self.eval_type == EVAL_DYNAMIC_CODE):
			p = parser.Parser(None, auth.get_current_user(), auth.get_registry())
			env = code.get_environment(None, p)
			env['this'] = self._vitals['host_object']
			self.value = code.r_eval(self.code, env)
		elif(self.eval_type == EVAL_ENTITY):
			from inner.space import entity
			if not(isinstance(self.value, entity.Entity)):
				self.value = auth.get_registry().get(self.value)
		return self.value
			
	def get_owner(self):
		"""
		Get the owner of this property.
		"""
		security.check_allowed(auth.get_current_user(), "read", self)
		return self._vitals['owner']
	
	def get_eval_type(self):
		security.check_allowed(auth.get_current_user(), "read", self)
		return self.eval_type
	
	def set_eval_type(self, eval_type):
		security.check_allowed(auth.get_current_user(), "write", self)
		self.eval_type = eval_type
	
	def is_readable(self):
		"""
		Is this property readable by the public?
		"""
		return security.is_allowed(auth.get_current_user(), 'read', self)
	
	def is_writeable(self):
		"""
		Is this property editable by the public?
		"""
		return security.is_allowed(auth.get_current_user(), 'write', self)
	
	def is_inherited(self):
		"""
		Does this property change ownership in descendents?
		TODO: make this work right
		"""
		return security.is_allowed(auth.get_current_user(), 'inherit', self)